﻿namespace Refract.UI.Docking
{
    using System.Windows;

    using Refract.Extensions;
    using Refract.Navigation;

    public class DockableService : DragService
    {
        #region Properties

        public IDock CurrentDock
        {
            get; set;
        }

        public bool IsDocked
        {
            get; set;
        }

        #endregion Properties

        #region Methods

        public override void Attach(FrameworkElement targetElement)
        {
            base.Attach(targetElement);

            Dragging += DockableService_Dragging;
            DragStopping += DockableService_DragStopping;
            DragStarted += DockableService_DragStarted;
        }

        public override void Detach()
        {
            base.Detach();
            Dragging -= DockableService_Dragging;
            DragStopping -= DockableService_DragStopping;
            DragStarting -= DockableService_DragStarted;
        }

        void DockableService_Dragging(object sender, DraggableEventArgs e)
        {
            var previousDock = CurrentDock;

            CurrentDock = null;

            foreach (FrameworkElement region in Region.RegionList)
            {
                var boundingBox = region.BoundingBox();

                if (boundingBox.Contains(Position))
                {
                    CurrentDock = region as IDock;
                    break;
                }
            }

            if (previousDock != CurrentDock)
            {
                if (previousDock != null) previousDock.Unhover(TargetElement, Position);
                if (CurrentDock != null) CurrentDock.Hover(TargetElement, Position);
            }
        }

        void DockableService_DragStarted(object sender, DraggableEventArgs e)
        {
            if(IsDocked)
            {
                CurrentDock.Undock(TargetElement, Position);
                IsDocked = false;
            }
        }

        void DockableService_DragStopping(object sender, DraggableEventArgs e)
        {
            if(CurrentDock != null && CurrentDock.CanDock(TargetElement, Position))
            {
                CurrentDock.Dock(TargetElement, Position);
                IsDocked = true;
            }
        }

        #endregion Methods
    }
}